package com.trust.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.trust.agri.exception.ServiceException;
import com.trust.agri.util.BeanUtil;
import com.trust.constant.Constants;
import com.trust.constant.InventoryTypeEnum;
import com.trust.entity.*;
import com.trust.entity.DTO.FarmPlantDTO;
import com.trust.entity.Param.FarmPlantListParam;
import com.trust.entity.VO.DictionaryVO;
import com.trust.entity.VO.FarmPlantVO;
import com.trust.entity.VO.PlantDropDown;
import com.trust.entity.result.DropDownResult;
import com.trust.mapper.FarmPlantMapper;
import com.trust.service.*;
import com.trust.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class FarmPlantServiceImpl extends ServiceImpl<FarmPlantMapper, FarmPlant> implements FarmPlantService {

    @Resource
    private MedicineService medicineService;

    @Resource
    private InventoryMaterialService inventoryMaterialService;

    @Resource
    private SetupLandService setupLandService;

    @Resource
    private FarmPlantLandService farmPlantLandService;

    @Resource
    private FarmSeedService farmSeedService;

    @Resource
    private PurchaseService purchaseService;

    @Resource
    private InventoryRecordService inventoryRecordService;
    @Override
    public Page<FarmPlantVO> list(FarmPlantListParam param) {
        LambdaQueryWrapper<FarmPlant> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(param.getCode())){
            wrapper.like(FarmPlant::getCode, param.getCode());
        }
        wrapper.eq(null != param.getCategoryId(), FarmPlant::getCategoryId, param.getCategoryId());
        wrapper.orderByDesc(FarmPlant::getId);
        Page<FarmPlant> page = this.page(new Page<>(param.getPageNum(), param.getPageSize()), wrapper);
        Page<FarmPlantVO> targetPage = BeanUtil.sourcePage2targetPage(page, FarmPlantVO.class);
        for (FarmPlantVO record : targetPage.getRecords()) {
            //种植品类
            record.setCategoryName(medicineService.getNameById(record.getCategoryId()));
            //种苗批号
            InventoryMaterial material = inventoryMaterialService.getById(record.getBreedCode());
            record.setBreedCodeName(material.getCode() + material.getMaterialName());
            //地块
            List<Integer> integers = JSON.parseArray(record.getPlantLand(), Integer.class);
            //当前进度
            record.setCropProgress(DateUtil.nowToDateOfYear(record.getPlantStart()));
            List<String> list =     new ArrayList<>();
            for (Integer integer : integers) {
                list.add(setupLandService.getCodeById(integer));
            }
            record.setPlantLandList(integers);
            record.setPlantLandCode(list);
            String s = list.toString();
            String replace = s.substring(1, s.length() - 1).replace("\"", "").replace(" ", "");
            record.setPlantLand(replace);
        }
        return targetPage;
    }

    @Override
    public FarmPlant getByCode(String code) {
        LambdaQueryWrapper<FarmPlant> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FarmPlant::getCode, code);
        return this.getOne(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FarmPlant saveAndUpdate(FarmPlantDTO param) {
        FarmPlant farmPlant = this.getByCode(param.getCode());
        if (null != param.getId()){
            farmPlantLandService.removeByPlantId(param.getId());
        }
        if (ObjectUtil.isNotEmpty(farmPlant)){
            if (null != param.getId() && !param.getId().equals(farmPlant.getId())){
                throw new ServiceException("种植批号重复！");
            }
        }
        //List<FarmPlantLand> farmPlantLands = farmPlantLandService.getByLandIds(param.getPlantLandList());
        //if (CollectionUtil.isNotEmpty(farmPlantLands)){
        //    if (farmPlantLands.size() > 1){
        //        throw new ServiceException("地块已有种植任务，请勿重复添加");
        //    }
        //    if (null == param.getId() || !param.getId().equals(farmPlantLands.get(0).getFarmPlantId())){
        //        throw new ServiceException("地块已有种植任务，请勿重复添加");
        //    }
        //}
        //
        //List<FarmSeedLand> farmSeedLands = farmSeedLandService.getByLandIds(param.getPlantLandList());
        //if (CollectionUtil.isNotEmpty(farmSeedLands)){
        //    throw new ServiceException("地块已有育苗任务，请勿重复添加");
        //}
        try {
            for (Integer landId : param.getPlantLandList()) {
                SetupLand land = setupLandService.getById(landId);
                if (land.getPlantType() != null && land.getPlantType() == 2) {
                    FarmSeed farmSeed = farmSeedService.getById(land.getCurrentPlantId());
                    Assert.isTrue(farmSeed == null || farmSeed.getState() == 2, "该地块已有育苗任务，请勿重复添加");
                }
                if (land.getPlantType() != null && land.getPlantType() == 1) {
                    FarmPlant farmPlantDb = this.getById(land.getCurrentPlantId());
                    Assert.isTrue(farmPlantDb == null || farmPlantDb.getState() == 2, "该地块已有种植任务，请勿重复添加");
                }
            }
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }

        FarmPlant target = BeanUtil.source2target(param, new FarmPlant());
        target.setState(1);
        target.setPlantLand(JSON.toJSONString(param.getPlantLandList()));
        this.saveOrUpdate(target);

        for (Integer integer : param.getPlantLandList()) {
            FarmPlantLand farmPlantLand = new FarmPlantLand(target.getId(), integer);
            farmPlantLandService.save(farmPlantLand);
        }

        for (Integer integer : param.getPlantLandList()) {
            SetupLand land = setupLandService.getById(integer);
            if (ObjectUtil.isEmpty(land)){
                throw new ServiceException("地块不存在" + integer);
            }
            land.setPlantCateId(param.getCategoryId());
            land.setColor(param.getColor());
            land.setCurrentPlantId(target.getId());
            land.setCurrentPlantCode(param.getCode());
            land.setPlantType(1);
            land.setStartTime(param.getPlantStart());
            setupLandService.updateById(land);
        }

        //出库
        String inCode = purchaseService.generalInCode();
        if (null == param.getId()){
            //库存
            InventoryMaterial material = inventoryMaterialService.getById(param.getBreedCode());
            if(new BigDecimal(param.getSeedNum()).compareTo(material.getStock()) > 0){
                throw  new ServiceException("库存不足");
            }
            material.setStock(material.getStock().subtract(BigDecimal.valueOf(param.getSeedNum())));
            inventoryMaterialService.updateById(material);

            //出入库记录
            InventoryRecord record = new InventoryRecord();
            record.setLinkCode(target.getCode());
            record.setStockCode(param.getBreedCodeName());
            record.setCode("C" + inCode);
            record.setUnitId(material.getUnitId());
            record.setUnit(material.getUnit());
            record.setMaterialId(material.getMaterialId());
            record.setMaterialName(material.getMaterialName());
            record.setStorehouseId(material.getStorehouseId());
            record.setInventoryTime(new Date());
            record.setNum(BigDecimal.valueOf(param.getSeedNum()));
            record.setMaterialType(-2);
            record.setMaterialTypeName("种苗");
            record.setInventoryType(Constants.PLANT_OUT);
            record.setMaterialCode(material.getCode());
            record.setParentId(target.getId());
            inventoryRecordService.save(record);
        } else {
            InventoryRecord inventoryRecord = inventoryRecordService.getByTypeAndParentId(InventoryTypeEnum.PLANT_OUT.getId(), param.getId());
            //库存
            InventoryMaterial material = inventoryMaterialService.getById(param.getBreedCode());
            material.setStock(material.getStock().subtract(BigDecimal.valueOf(param.getSeedNum())).add(inventoryRecord.getNum()));
            inventoryMaterialService.updateById(material);

            //出入库记录
            inventoryRecordService.removeByParentId(param.getId());
            InventoryRecord record = new InventoryRecord();
            record.setLinkCode(farmPlant.getCode());
            record.setStockCode(param.getBreedCodeName());
            record.setCode("C" + inCode);
            record.setUnitId(material.getUnitId());
            record.setUnit(material.getUnit());
            record.setMaterialId(material.getMaterialId());
            record.setMaterialName(material.getMaterialName());
            record.setStorehouseId(material.getStorehouseId());
            record.setInventoryTime(new Date());
            record.setNum(BigDecimal.valueOf(param.getSeedNum()));
            record.setMaterialType(-2);
            record.setMaterialTypeName("种苗");
            record.setInventoryType(Constants.PLANT_OUT);
            record.setMaterialCode(material.getCode());
            record.setParentId(param.getId());
            inventoryRecordService.save(record);
        }
        return target;
    }

    @Override
    public List<DropDownResult> dropDown() {
        LambdaQueryWrapper<FarmPlant> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FarmPlant::getState, 1)
                .orderByDesc(FarmPlant::getId);
        List<FarmPlant> list = this.list(wrapper);
        List<DropDownResult> results = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(list)){
            for (FarmPlant farmPlant : list) {
                DropDownResult drop = new DropDownResult(farmPlant.getId(), farmPlant.getCode());
                results.add(drop);
            }
        }
        return results;
    }

    @Override
    public List<PlantDropDown> dropDownList() {
        LambdaQueryWrapper<FarmPlant> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FarmPlant::getState, 1);
        List<FarmPlant> list = this.list(wrapper);
        List<PlantDropDown> dropDownList = new ArrayList<>();
        for (FarmPlant farmPlant : list) {
            PlantDropDown drop = new PlantDropDown();
            drop.setId(farmPlant.getId());
            drop.setPlantCode(farmPlant.getCode());
            List<Integer> integers = JSON.parseArray(farmPlant.getPlantLand(), Integer.class);
            List<DictionaryVO> lands = new ArrayList<>();
            for (Integer integer : integers) {
                DictionaryVO vo = new DictionaryVO();
                vo.setId(integer);
                vo.setName(setupLandService.getCodeById(integer));
                lands.add(vo);
            }
            drop.setLands(lands);
            drop.setName(farmPlant.getCode());
            dropDownList.add(drop);
        }
        return dropDownList;
    }


    @Override
    public String getCateNameById(Integer id) {
        FarmPlant plant = this.getById(id);
        if (null == plant){
            return "";
        }
        return medicineService.getNameById(plant.getCategoryId());
    }
}
